﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EasyTrader.Option
{
    using CodeList = List<EasyTrader.DataSet.CodeTable>;
    using DDECollectionList = List<EasyTrader.Option.DDEData>;
    using SimpleDataList = List<EasyTrader.DataSet.SimpleData>;

    public partial class FlowTable : System.Windows.Forms.Form
    {
#region Internal Class
        public class CellDoubleClickEvent : SourceGrid.Cells.Controllers.ControllerBase
        {
            private EasyTrader.Option.FlowTable m_DDEFrm = null;
            public EasyTrader.Option.FlowTable DDEFrm
            {
                get { return m_DDEFrm; }
                set { m_DDEFrm = value; }
            }
            

            private SourceGrid.Grid m_GridDDE = null;
            public SourceGrid.Grid GridDDE
            {
                get { return m_GridDDE; }
                set { m_GridDDE = value; }
            }

            public override void OnDoubleClick(SourceGrid.CellContext sender, EventArgs e)
            {
                base.OnDoubleClick(sender, e);
                SourceGrid.Cells.Cell curCell = (SourceGrid.Cells.Cell)sender.Cell;
                //MessageBox.Show(sender.Grid, curCell.Column.Index.ToString() + curCell.Row.Index.ToString());
                //if (m_DDEFrm.TargetValueFilled == true)
                //{
                    //EasyTrader.Chart.CallPutChart callPutChart = new EasyTrader.Chart.CallPutChart(m_DDEFrm.OpDataSet);
                    //callPutChart.Show();
                //}
                SourceGrid.Grid gridPrice = (SourceGrid.Grid)sender.Grid;
                //string closeVal = gridPrice[m_OrderFrm.centerRow, 3].Value.ToString();
                //if (closeVal == "")
                //    return;


            }
        }
#endregion

#region Member Functions
        public void SetATM()
        {
            string callATM = m_OpDataSet.DownLoader.CallATM;
            if (callATM != "")
            {
                int curRow = 0;
                string atm = callATM.Substring(callATM.Length - 3, 3);
                for (int i = 2; i < gridDDE.RowsCount; i++)
                {
                    string pVal = gridDDE[i, 6].Value.ToString();
                    if (atm == pVal)
                    {
                        curRow = i;
                        break;
                    }
                }

                if (curRow != 0)
                {
                    gridDDE[curRow, 6].View = priceView;
                }
            }
        }

        private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        private void InitTimer()
        {
            timer.Interval = 1000;
            timer.Tick += new EventHandler(OnTimerTick);
            timer.Start();
        }

        // 여기서 차트를 갱신해 준다.
        private void OnTimerTick(object sender, EventArgs e)
        {
            if (m_OpDataSet.DownLoader.AllOptChartDataDownloaded == false ||
                m_OpDataSet.DownLoader.ATMChanged == false)
                return;

            FillCurVal();
        }
#endregion
        
#region Member Variables

        private int m_CellWidth = 60;
        private EasyTrader.ETDataSet m_OpDataSet = null;


        private SourceGrid.Cells.Views.Cell categoryView = null;
        private SourceGrid.Cells.Views.Cell headerView = null;
        private SourceGrid.Cells.Views.Cell priceView = null;
        private SourceGrid.Cells.Views.Cell buyView = null;
        private SourceGrid.Cells.Views.Cell sellView = null;
        private SourceGrid.Cells.Views.Cell centerView = null;
        private SourceGrid.Cells.Views.Cell normalView = null;

        private SourceGrid.Cells.Views.Cell highView = null;
        private SourceGrid.Cells.Views.Cell lowView = null;
        private SourceGrid.Cells.Views.Cell baseView = null;
        private SourceGrid.Cells.Views.Cell curView = null;

        private SourceGrid.Cells.Views.Cell upView = null;
        private SourceGrid.Cells.Views.Cell downView = null;
#endregion

#region  Grid Init
        public FlowTable()
        {
            InitializeComponent();
        }

        public FlowTable(EasyTrader.ETDataSet opDataSet)
        {
            m_OpDataSet = opDataSet;
            InitializeComponent();
            InitGridCellView();
            InitGrid();
            m_OpDataSet.CreateDDEData();
            SetATM();
            FillCrossData();
            FillCurVal();
            InitTimer();
        }

        private void InitGrid()
        {
            if (m_OpDataSet == null)
                return;

            CellDoubleClickEvent doubleClickController = new CellDoubleClickEvent();
            doubleClickController.GridDDE = gridDDE;
            doubleClickController.DDEFrm = this;


            gridDDE.Redim(30, 13);
            gridDDE.FixedRows = 2;
            gridDDE.Rows[0].Height = 30;

            gridDDE[0, 0] = new SourceGrid.Cells.Cell("콜옵션");
            gridDDE[0, 0].SetSpan(1, 5);
            gridDDE[0, 0].View = buyView;
            gridDDE[1, 5] = new SourceGrid.Cells.Cell("현재가");
            gridDDE[1, 5].SetSpan(1, 1);
            gridDDE[1, 5].View = headerView;
            gridDDE[1, 5].Column.Width = m_CellWidth;
            gridDDE[0, 5] = new SourceGrid.Cells.Cell("행사가격");
            gridDDE[0, 5].SetSpan(1, 3);
            gridDDE[0, 5].View = headerView;
            gridDDE[0, 5].Column.Width = 120;
            gridDDE[1, 7] = new SourceGrid.Cells.Cell("현재가");
            gridDDE[1, 7].SetSpan(1, 1);
            gridDDE[1, 7].View = headerView;
            gridDDE[1, 7].Column.Width = m_CellWidth;

            gridDDE[0, 8] = new SourceGrid.Cells.Cell("풋옵션");
            gridDDE[0, 8].SetSpan(1, 5);
            gridDDE[0, 8].View = sellView;

            gridDDE[1, 0] = new SourceGrid.Cells.Cell("월저가");
            gridDDE[1, 0].View = buyView;
            gridDDE[1, 0].Column.Width = m_CellWidth;
            gridDDE[1, 1] = new SourceGrid.Cells.Cell("마디가");
            gridDDE[1, 1].View = buyView;
            gridDDE[1, 1].Column.Width = m_CellWidth;
            gridDDE[1, 2] = new SourceGrid.Cells.Cell("기준가");
            gridDDE[1, 2].View = buyView;
            gridDDE[1, 2].Column.Width = m_CellWidth;
            gridDDE[1, 3] = new SourceGrid.Cells.Cell("목표가");
            gridDDE[1, 3].View = buyView;
            gridDDE[1, 3].Column.Width = m_CellWidth;
            gridDDE[1, 4] = new SourceGrid.Cells.Cell("월고가");
            gridDDE[1, 4].View = buyView;
            gridDDE[1, 4].Column.Width = m_CellWidth;
            gridDDE[1, 8] = new SourceGrid.Cells.Cell("월고가");
            gridDDE[1, 8].View = sellView;
            gridDDE[1, 8].Column.Width = m_CellWidth;
            gridDDE[1, 9] = new SourceGrid.Cells.Cell("목표가");
            gridDDE[1, 9].View = sellView;
            gridDDE[1, 9].Column.Width = m_CellWidth;
            gridDDE[1, 10] = new SourceGrid.Cells.Cell("기준가");
            gridDDE[1, 10].View = sellView;
            gridDDE[1, 10].Column.Width = m_CellWidth;
            gridDDE[1, 11] = new SourceGrid.Cells.Cell("마디가");
            gridDDE[1, 11].View = sellView;
            gridDDE[1, 11].Column.Width = m_CellWidth;
            gridDDE[1, 12] = new SourceGrid.Cells.Cell("월저가");
            gridDDE[1, 12].View = sellView;
            gridDDE[1, 12].Column.Width = m_CellWidth;

            // Fill Price Range
            for (int i = 2; i < gridDDE.RowsCount; i++)
            {
                gridDDE[i, 5] = new SourceGrid.Cells.Cell();
                gridDDE[i, 7] = new SourceGrid.Cells.Cell();
                gridDDE[i, 5].View = curView;
                gridDDE[i, 5].Column.Width = m_CellWidth;
                gridDDE[i, 7].View = curView;
                gridDDE[i, 7].Column.Width = m_CellWidth;
            }

            for (int i = 2; i < gridDDE.RowsCount; i++)
            {
                gridDDE[i, 6] = new SourceGrid.Cells.Cell();
                gridDDE[i, 6].View = centerView;
                //gridDDE[i, 6].SetSpan(3, 1);
                gridDDE[i, 6].Column.Width = m_CellWidth;
            }

            // Fill call side
            for (int i = 2; i < gridDDE.RowsCount; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    gridDDE[i, j] = new SourceGrid.Cells.Cell();
                    gridDDE[i, j].View = highView;
                    gridDDE[i, j].Column.Width = m_CellWidth;
                }
            }

            for (int i = 2; i < gridDDE.RowsCount; i++)
            {
                for (int j = 8; j < 13; j++)
                {
                    gridDDE[i, j] = new SourceGrid.Cells.Cell();
                    gridDDE[i, j].View = lowView;
                    gridDDE[i, j].Column.Width = m_CellWidth;
                }
            }


            CodeList centerCodeList = m_OpDataSet.DownLoader.CenterPriceCodeList;
            CodeList callCodeList = m_OpDataSet.DownLoader.CallPriceCodeList;
            CodeList putCodeList = m_OpDataSet.DownLoader.PutPriceCodeList;

            for (int i = 2, j = 0; i < gridDDE.RowsCount && j < m_OpDataSet.DownLoader.PriceCodeList.Count; i++, j++)
            {
                gridDDE[i, 6].Value = m_OpDataSet.DownLoader.PriceCodeList[m_OpDataSet.DownLoader.PriceCodeList.Count - j - 1];
                gridDDE[i, 6].AddController(doubleClickController);
                string callCode = callCodeList[callCodeList.Count - j - 1].Code;
                string putCode = putCodeList[putCodeList.Count - j - 1].Code;
            }

            //m_OpDataSet.DownLoader.StartTimer();
        }


        public void InitGridCellView()
        {
            DevAge.Drawing.RectangleBorder border = new DevAge.Drawing.RectangleBorder(new DevAge.Drawing.BorderLine(Color.DarkGreen), new DevAge.Drawing.BorderLine(Color.DarkGreen));
            //Category header
            //DevAge.Drawing.BorderLine top = new DevAge.Drawing.BorderLine(Color.Blue, 2);
            //DevAge.Drawing.RectangleBorder rcBorder = new DevAge.Drawing.RectangleBorder();

            categoryView = new SourceGrid.Cells.Views.Cell();
            categoryView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.RoyalBlue, Color.LightBlue, 0);
            categoryView.ForeColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            categoryView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            categoryView.Border = DevAge.Drawing.RectangleBorder.NoBorder;
            categoryView.Font = new Font("굴림", 9, FontStyle.Bold);


            headerView = new SourceGrid.Cells.Views.Cell();
            headerView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.ForestGreen, Color.FloralWhite, 0);
            headerView.ForeColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            headerView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            headerView.Border = DevAge.Drawing.RectangleBorder.NoBorder;
            headerView.Font = new Font("굴림", 9, FontStyle.Bold);

            priceView = new SourceGrid.Cells.Views.Cell();
            priceView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.ForestGreen, Color.ForestGreen, 0);
            //priceView.ForeColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            priceView.ForeColor = Color.White;
            priceView.BackColor = Color.LightSteelBlue;
            priceView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            priceView.Border = DevAge.Drawing.RectangleBorder.RectangleBlack1Width;
            priceView.Font = new Font("굴림", 9, FontStyle.Regular);

            buyView = new SourceGrid.Cells.Views.Cell();
            buyView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.Red, Color.White, 0);
            //priceView.ForeColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            buyView.BackColor = Color.LightPink;
            buyView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            //priceView.Border = DevAge.Drawing.RectangleBorder.NoBorder;
            buyView.Font = new Font("굴림", 9, FontStyle.Regular);

            sellView = new SourceGrid.Cells.Views.Cell();
            sellView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.Blue, Color.White, 0);
            //priceView.ForeColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            sellView.BackColor = Color.LightSteelBlue;
            sellView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            //priceView.Border = DevAge.Drawing.RectangleBorder.NoBorder;
            sellView.Font = new Font("굴림", 9, FontStyle.Regular);

            centerView = new SourceGrid.Cells.Views.Cell();
            centerView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.FloralWhite, Color.LightSteelBlue, 90);
            centerView.ForeColor = Color.Red;
            centerView.BackColor = Color.LightSteelBlue;
            centerView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            //priceView.Border = DevAge.Drawing.RectangleBorder.NoBorder;
            centerView.Font = new Font("굴림", 9, FontStyle.Regular);

            normalView = new SourceGrid.Cells.Views.Cell();
            //normalView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.ForestGreen, Color.FloralWhite, 0);
            normalView.ForeColor = Color.Black;
            normalView.BackColor = Color.White;
            normalView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            normalView.Font = new Font("굴림", 9, FontStyle.Regular);


            highView = new SourceGrid.Cells.Views.Cell();
            highView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.LightPink, Color.White, 90);
            highView.ForeColor = Color.Black;
            highView.BackColor = Color.White;
            highView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            highView.Font = new Font("굴림", 9, FontStyle.Regular);

            lowView = new SourceGrid.Cells.Views.Cell();
            lowView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.LightBlue, Color.White, 90);
            lowView.ForeColor = Color.Black;
            lowView.BackColor = Color.White;
            lowView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            //lowView.Border. = DevAge.Drawing.BorderLine;
            lowView.Font = new Font("굴림", 9, FontStyle.Regular);


            baseView = new SourceGrid.Cells.Views.Cell();
            baseView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.LightGreen, Color.White, 90);
            baseView.ForeColor = Color.Red;
            baseView.BackColor = Color.White;
            baseView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            baseView.Font = new Font("굴림", 9, FontStyle.Bold);

            curView = new SourceGrid.Cells.Views.Cell();
            //curView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.White, Color.White, 90);
            curView.ForeColor = Color.Black;
            curView.BackColor = Color.White;
            curView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            curView.Font = new Font("굴림", 9, FontStyle.Regular);


            upView = new SourceGrid.Cells.Views.Cell();
            upView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.LightGreen, Color.White, 90);
            upView.ForeColor = Color.Red;
            upView.BackColor = Color.White;
            upView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            upView.Font = new Font("굴림", 9, FontStyle.Regular);

            downView = new SourceGrid.Cells.Views.Cell();
            downView.Background = new DevAge.Drawing.VisualElements.BackgroundLinearGradient(Color.LightGreen, Color.White, 90);
            downView.ForeColor = Color.Blue;
            downView.BackColor = Color.White;
            downView.TextAlignment = DevAge.Drawing.ContentAlignment.MiddleCenter;
            downView.Font = new Font("굴림", 9, FontStyle.Regular);

        }
#endregion

#region Fill Process

        private void FillCurVal()
        {
            if (m_OpDataSet == null)
                return;
            for (int i = 0; i < m_OpDataSet.OptChartTableList.Count; i++)
            {
                EasyTrader.DataSet.BarDataTable table = m_OpDataSet.OptChartTableList[i];
                string priceCode = table.TableName;
                priceCode = priceCode.Substring(priceCode.Length - 3, 3);
                int rowID = FindRowID(priceCode);
                string opCode = table.TableName;
                int rowCount = table.GetRowCount();
                if (rowCount > 0)
                {
                    DataRow row = table.Rows[rowCount - 1];
                    double close  = Convert.ToDouble(row["종가"]);
                    string sideCode = opCode.Substring(0, 1);
                    if (sideCode == "2")
                        gridDDE[rowID, 5].Value = close;
                    else if (sideCode == "3")
                        gridDDE[rowID, 7].Value = close;
                }
            }
        }

        private void FillCrossData()
        {
            EasyTrader.Option.DDEDayData dayDataCol = m_OpDataSet.FindDDEDayData(m_OpDataSet.DownLoader.CurDay);
            DDECollectionList dataList = dayDataCol.CollectionList;
            for (int i = 0; i < dataList.Count; i++)
            {
                DDEData curRowData = dataList[dataList.Count - 1 - i];
                int rowID = i + 2;
                gridDDE[rowID, 0].Value = curRowData.DataItem.CallMLow;
                gridDDE[rowID, 1].Value = curRowData.CallJoint;
                if (curRowData.PriceCode.ToString() == curRowData.CallJointCenter)
                    gridDDE[rowID, 1].View = buyView;
                gridDDE[rowID, 2].Value = curRowData.DataItem.CallBase;
                gridDDE[rowID, 3].Value = curRowData.CallTarget;
                if (curRowData.PriceCode.ToString() == curRowData.CallTargetCenter)
                    gridDDE[rowID, 3].View = buyView;
                gridDDE[rowID, 4].Value = curRowData.DataItem.CallMHigh;

                gridDDE[rowID, 12].Value = curRowData.DataItem.PutMLow;
                gridDDE[rowID, 11].Value = curRowData.PutJoint;
                if (curRowData.PriceCode.ToString() == curRowData.PutJointCenter)
                    gridDDE[rowID, 11].View = buyView;
                gridDDE[rowID, 10].Value = curRowData.DataItem.PutBase;
                gridDDE[rowID, 9].Value = curRowData.PutTarget;
                if (curRowData.PriceCode.ToString() == curRowData.PutTargetCenter)
                    gridDDE[rowID, 9].View = buyView;
                gridDDE[rowID, 8].Value = curRowData.DataItem.PutMHigh;
            }

            /*
            if (m_OpDataSet.OptCrossMonthData.Count > 0)
            {
                EasyTrader.DataSet.DayCrossData dayCrossData = m_OpDataSet.OptCrossMonthData[m_OpDataSet.OptCrossMonthData.Count - 1];
                SimpleDataList crossDataList = dayCrossData.DataList;
                for (int j = 0; j < crossDataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = crossDataList[j];
                    int row = FindRowID(curData.PriceCode);
                    if (curData.CallType == 0)
                    {
                        gridDDE[row, 1].Value = curData.CallVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 1].View = buyView;
                    }
                    if (curData.CallType == 1)
                    {
                        gridDDE[row, 3].Value = curData.CallVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 3].View = buyView;
                    }
                    if (curData.PutType == 0)
                    {
                        gridDDE[row, 11].Value = curData.PutVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 11].View = buyView;
                    }
                    if (curData.PutType == 1)
                    {
                        gridDDE[row, 9].Value = curData.PutVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 9].View = buyView;
                    }
                }
            }

            if (m_OpDataSet.OptCrossMonthData.Count > 1)
            {
                EasyTrader.DataSet.DayCrossData dayCrossData = m_OpDataSet.OptCrossMonthData[m_OpDataSet.OptCrossMonthData.Count - 2];
                SimpleDataList crossDataList = dayCrossData.DataList;
                for (int j = 0; j < crossDataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = crossDataList[j];
                    int row = FindRowID(curData.PriceCode);
                    if (curData.CallType == 0)
                    {
                        gridDDE[row, 1].Value = curData.CallVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 1].View = buyView;
                    }
                    if (curData.CallType == 1)
                    {
                        gridDDE[row, 3].Value = curData.CallVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 3].View = buyView;
                    }
                    if (curData.PutType == 0)
                    {
                        gridDDE[row, 11].Value = curData.PutVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 11].View = buyView;
                    }
                    if (curData.PutType == 1)
                    {
                        gridDDE[row, 9].Value = curData.PutVal;
                        if (curData.PriceCode == curData.CenterVal)
                            gridDDE[row, 9].View = buyView;
                    }
                }
            }*/
        }

        private int FindRowID(string a_PriceCode)
        {
            int rowID = 0;

            int rowCount = gridDDE.RowsCount;
            for (int i = 2; i < rowCount; i++)
            {
                object value = gridDDE[i, 6].Value;

                if (value.ToString() == a_PriceCode)
                {
                    rowID = i;
                    break;
                }
            }

            return rowID;
        }
#endregion
    }
}
